﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Insteon
{
    internal class Flags
    {
        internal enum MessageType
        {
            Broadcast = 0x80,
            Direct = 000,
            ACKofDirect = 0x20,
            NAKofDirect = 0xA0,
            AllLinkBroadcast = 0xC0,
            ALLLinkCleanup = 0x40,
            AckAllLinkCleanup = 0x60,
            NakAllLinkCleanup = 0xE0
        }

        internal readonly MessageType Type;
        internal readonly bool Extended;
        internal readonly uint HopsLeft;
        internal readonly uint MaxHops;
        internal readonly byte BinFlags;

        internal Flags(MessageType Type, bool Extended)
        {
            this.Type = Type;
            BinFlags = (byte)Type;

            this.Extended = Extended;
            if (Extended == true)
            {
                BinFlags = (byte) ((byte) BinFlags + 0x10);
            }
            
            HopsLeft = 3;
            BinFlags = (byte)((byte)BinFlags + 0xC);
            
            MaxHops = 3;
            BinFlags = (byte)((byte)BinFlags + 0x3);
        }

        internal Flags(byte Byte){
            BinFlags = Byte;
            string ByteString = Convert.ToString(Byte, 2).PadLeft(8, '0');

            Byte bType = Byte;
            Byte bExtended = Byte;
            Byte bHopsLeft = Byte;
            Byte bMaxHops = Byte;

            //use masks and "or" to isolate bits
            bType = (byte)((UInt16) Byte & (UInt16) 0xE0);
            bExtended = (byte)((UInt16)Byte & (UInt16)0x10);
            bHopsLeft = (byte)((UInt16)Byte & (UInt16)0xC);
            bMaxHops = (byte)((UInt16)Byte & (UInt16)0x3);

            string TypeByteString = Convert.ToString(bType, 2).PadLeft(8, '0');

            MaxHops = bMaxHops;

            HopsLeft = bHopsLeft;
            HopsLeft = HopsLeft >> 2;

            //now check to see if they equal a mask, if so they must be that.
            if (bExtended == 0x10)
            {
                Extended = true;
            }
            else
            {
                Extended = false;
            }

            switch ((UInt16) bType)
            {
                case (UInt16) MessageType.AckAllLinkCleanup:
                    Type = MessageType.AckAllLinkCleanup;
                    break;
                case (UInt16)MessageType.ACKofDirect  :
                    Type = MessageType.ACKofDirect  ;
                    break;
                case (UInt16)MessageType.AllLinkBroadcast:
                    Type = MessageType.AllLinkBroadcast;
                    break;
                case (UInt16)MessageType.ALLLinkCleanup:
                    Type = MessageType.ALLLinkCleanup;
                    break;
                case (UInt16)MessageType.Broadcast:
                    Type = MessageType.Broadcast;
                    break;
                case (UInt16)MessageType.Direct:
                    Type = MessageType.Direct;
                    break;
                case (UInt16)MessageType.NakAllLinkCleanup:
                    Type = MessageType.NakAllLinkCleanup;
                    break;
                case (UInt16)MessageType.NAKofDirect:
                    Type = MessageType.NAKofDirect;
                    break;
            }
        }

        public override string ToString()
        {
            return string.Format("Flags: {0,-16} {1,-5} {2} {3}", Type, Extended, HopsLeft, MaxHops);
        }

    }
}
